getMenuByRoleid<template>
  <el-card class="page_card">
    <el-form :inline="true" class="form">
      <el-form-item label="菜单名称：">
        <el-input v-model="data.keyword" placeholder="请输入菜单名称"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" color="#626aef" @click="search" 
          :disabled="data.keyword?false:true">搜索</el-button>
        <el-button @click="reset" color="#626aef" plain>重置</el-button>
      </el-form-item>
    </el-form>
    <el-button type="primary" icon="Plus" @click="addMenu">添加菜单</el-button>
    <el-table border :data="data.menuTableData" row-key="id" :height="710">
      <el-table-column label="序号" align="center" prop="order" :width="130"></el-table-column>
      <el-table-column label="菜单项值" align="center" prop="menuId"></el-table-column>
      <el-table-column label="菜单名称" align="center" prop="menuName"></el-table-column>
      <el-table-column label="路由路径" align="center" prop="menuUrl"></el-table-column>
      <el-table-column label="菜单图标" align="center" prop="menuIcon"></el-table-column>
      <el-table-column label="操作" width="270px" align="left" header-align="center">
        <template #="{row}">
          <el-button type="primary" link icon="Edit" @click="updateMenu(row)">编辑</el-button>
          <el-button type="primary" link icon="Plus" @click="addMenuRow(row)" v-if="row.parentId==0">添加</el-button>
          <el-popconfirm :title="`确认删除${row.menuName}吗？`" width="240px" 
            @confirm="deleteMenu(row)" v-if="row.children.length==0">
            <template #reference>
              <el-button type="danger" link icon="Delete" :disabled="row.menuId=='Home'">删除</el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
  </el-card>
  <!-- 添加菜单、更新菜单 -->
  <el-dialog v-model="data.addMenuDialog" :title="data.menuForm.id?'更新菜单':'添加菜单'" width="650">
    <el-form :model="data.menuForm" :rules="data.rules" ref="formRef" label-width="130px" style="max-width: 550px">
      <el-form-item label="上级菜单" prop="parentId">
        <el-select v-model="data.menuForm.parentId" placeholder="请选择上级菜单" >
          <el-option label="根菜单" :value="0"/>
          <el-option v-for="item in data.parentIdList" :key="item.id" :label="item.menuName" :value="item.id"/>
        </el-select>
      </el-form-item>
      <el-form-item label="菜单项值" prop="menuId">
        <el-input v-model="data.menuForm.menuId" placeholder="请输入菜单项ID"></el-input>
      </el-form-item>
      <el-form-item label="菜单项名称" prop="menuName">
        <el-input v-model="data.menuForm.menuName" placeholder="请输入菜单项名称"></el-input>
      </el-form-item>
      <el-form-item label="路由路径" prop="menuUrl">
        <el-input v-model="data.menuForm.menuUrl" placeholder="请输入路由路径"></el-input>
      </el-form-item>
      <el-form-item label="菜单图标" prop="menuIcon">
        <el-input v-model="data.menuForm.menuIcon" placeholder="请输入菜单图标"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="save">确定</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import {ref,onMounted,reactive,nextTick} from 'vue'
import {reqAllMenu,reqAddOrUpdateMenu,reqRemoveMenu} from '@/api/sys/menuApi'
import type { Menu,MenuResData } from '@/api/sys/menuType'
import { ElMessage } from 'element-plus'
import useLayOutSettingStore from '@/store/modules/setting'

let settingStore = useLayOutSettingStore() // 模板setting仓库
let formRef = ref<any>() //form表单实例
const data = reactive({
  keyword:'',
  menuTableData:[] as Menu[],
  addMenuDialog:false, //新增对话框
  menuForm:{ //新增表单
    parentId:0,
    menuId:'', 
    menuName:'', 
    menuUrl:'', 
    menuIcon:'', 
    id:'',
  },
  parentIdList:[] as Menu[], //上级菜单下拉框
  rules:{
    menuId:[{ required: true, trigger: 'blur', message:'请输入菜单项ID'}],
    menuName:[{ required: true, trigger: 'blur', message:'请输入菜单项名称'}],
    menuUrl:[{ required: true, trigger: 'blur', message:'请输入路由路径'}],
  }
})

onMounted(() => {
  initMenuData()
})

// 搜索
const search = ()=>{
  initMenuData(data.keyword)
}
// 重置
const reset = ()=>{
  settingStore.refsh = !settingStore.refsh
}
// 获取菜单列表
const initMenuData = async(menuName='')=> {
  let res:MenuResData = await reqAllMenu(menuName)
  if(res.code==200){
    data.menuTableData = generateTreeData(res.data.records)
    data.parentIdList = res.data.records.filter((item:any) => {
      return item.parentId == 0
    })
  }
}
// 递归生成菜单树
const generateTreeData = (treeData:any, parentId = 0, parentOrder = '') => {
  let tree:any = []
  let currentIndex = 1
  treeData.forEach((item:any) => {  
    if (item.parentId === parentId) { 
      // 生成当前项order字段
      const currentOrder = `${parentOrder}${parentOrder ? '.' : ''}${currentIndex}`
      item.order = currentOrder
      // 递归子项
      const children = generateTreeData(treeData, item.id, currentOrder)
      item.children = children
      tree.push(item)
      currentIndex++
    }  
  });  
  return tree
}
// 新增对话框
const addMenu = ()=> {
  data.addMenuDialog = true
  // 清空数据
  Object.assign(data.menuForm,{
    parentId:0,
    menuId:'', 
    menuName:'', 
    menuUrl:'', 
    menuIcon:'', 
    id:'',
  })
  nextTick(() => {
    // 清除上一次错误提示信息
    formRef.value.clearValidate('menuId')
    formRef.value.clearValidate('menuName')
    formRef.value.clearValidate('menuUrl')
  })
}
// 编辑对话框
const updateMenu = (row:Menu)=> {
  data.addMenuDialog = true
  Object.assign(data.menuForm,row)
  nextTick(() => {
    // 清除上一次错误提示信息
    formRef.value.clearValidate('menuId')
    formRef.value.clearValidate('menuName')
    formRef.value.clearValidate('menuUrl')
  })
}
// 新增/编辑确认
const save = async() => {
  try{
    await formRef.value.validate()
    let res = await reqAddOrUpdateMenu(data.menuForm)
    if(res.code==200){
      data.addMenuDialog = false
      ElMessage.success(data.menuForm.id?'更新成功！':'添加成功！')
      initMenuData()
    }else{
      data.addMenuDialog = false
      ElMessage.error(data.menuForm.id?'更新失败！':'添加失败！')
    }
  }catch (error) {}
}
const cancel = ()=>{
  data.addMenuDialog = false
}

// 行数据 添加菜单
const addMenuRow = async(row:Menu)=> {
  data.addMenuDialog = true
  // 清空数据
  Object.assign(data.menuForm,{
    parentId:row.id,
    menuId:'', 
    menuName:'', 
    menuUrl:'', 
    menuIcon:'', 
    id:'',
  })
  nextTick(() => {
    // 清除上一次错误提示信息
    formRef.value.clearValidate('menuId')
    formRef.value.clearValidate('menuName')
    formRef.value.clearValidate('menuUrl')
  })
}

// 删除单行菜单
const deleteMenu = async(row:Menu)=>{
  let res = await reqRemoveMenu((row.id as number),row.version)
  if(res.code==200){
    ElMessage.success('删除成功！')
    initMenuData()
  }else{
    ElMessage.error('删除失败！')
  }
}
</script>

<style scoped lang="scss">

</style>


